home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / m_flyer.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-13  |  13.6 KB  |  572 lines

  1. /*
  2. ==============================================================================
  3.  
  4. flyer
  5.  
  6. ==============================================================================
  7. */
  8.  
  9. #include "g_local.h"
  10. #include "m_flyer.h"
  11.  
  12. qboolean visible (edict_t *self, edict_t *other);
  13.  
  14. static int    nextmove;            // Used for start/stop frames
  15.  
  16. static int    sound_sight;
  17. static int    sound_idle;
  18. static int    sound_pain1;
  19. static int    sound_pain2;
  20. static int    sound_slash;
  21. static int    sound_sproing;
  22. static int    sound_die;
  23.  
  24.  
  25. void flyer_check_melee(edict_t *self);
  26. void flyer_loop_melee (edict_t *self);
  27. void flyer_melee (edict_t *self);
  28. void flyer_setstart (edict_t *self);
  29. void flyer_stand (edict_t *self);
  30. void flyer_nextmove (edict_t *self);
  31.  
  32.  
  33. void flyer_sight (edict_t *self, edict_t *other)
  34. {
  35.     gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
  36. }
  37.  
  38. void flyer_idle (edict_t *self)
  39. {
  40.     gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
  41. }
  42.  
  43. void flyer_pop_blades (edict_t *self)
  44. {
  45.     gi.sound (self, CHAN_VOICE, sound_sproing, 1, ATTN_NORM, 0);
  46. }
  47.  
  48.  
  49. mframe_t flyer_frames_stand [] =
  50. {
  51.     
  52.     ai_stand, 0, NULL,
  53.     ai_stand, 0, NULL,
  54.     ai_stand, 0, NULL,
  55.     ai_stand, 0, NULL,
  56.     ai_stand, 0, NULL,
  57.     ai_stand, 0, NULL,
  58.     ai_stand, 0, NULL,
  59.     ai_stand, 0, NULL,
  60.     ai_stand, 0, NULL,
  61.     ai_stand, 0, NULL,
  62.     ai_stand, 0, NULL,
  63.     ai_stand, 0, NULL
  64. };
  65. mmove_t    flyer_move_stand = {FRAME_hover01, FRAME_hover12, flyer_frames_stand, NULL};
  66.  
  67.  
  68. mframe_t flyer_frames_walk [] =
  69. {
  70.     
  71.     ai_walk, 5, NULL,
  72.     ai_walk, 5, NULL,
  73.     ai_walk, 5, NULL,
  74.     ai_walk, 5, NULL,
  75.     ai_walk, 5, NULL,
  76.     ai_walk, 5, NULL,
  77.     ai_walk, 5, NULL,
  78.     ai_walk, 5, NULL,
  79.     ai_walk, 5, NULL,
  80.     ai_walk, 5, NULL,
  81.     ai_walk, 5, NULL,
  82.     ai_walk, 5, NULL
  83. };
  84. mmove_t    flyer_move_walk = {FRAME_fly01, FRAME_fly12, flyer_frames_walk, NULL};
  85.  
  86. mframe_t flyer_frames_run [] =
  87. {
  88.     
  89.     
  90.     ai_run, 10, NULL,
  91.     ai_run, 10, NULL,
  92.     ai_run, 10, NULL,
  93.     ai_run, 10, NULL,
  94.     ai_run, 10, NULL,
  95.     ai_run, 10, NULL,
  96.     ai_run, 10, NULL,
  97.     ai_run, 10, NULL,
  98.     ai_run, 10, NULL,
  99.     ai_run, 10, NULL,
  100.     ai_run, 10, NULL,
  101.     ai_run, 10, NULL
  102. };
  103. mmove_t    flyer_move_run = {FRAME_fly01, FRAME_fly12, flyer_frames_run, NULL};
  104.  
  105. void flyer_run (edict_t *self)
  106. {
  107.     if (self->monsterinfo.aiflags & AI_STAND_GROUND)
  108.         self->monsterinfo.currentmove = &flyer_move_stand;
  109.     else
  110.         self->monsterinfo.currentmove = &flyer_move_run;
  111. }
  112.  
  113. void flyer_walk (edict_t *self)
  114. {
  115.     self->monsterinfo.currentmove = &flyer_move_walk;
  116. }
  117.  
  118. void flyer_stand (edict_t *self)
  119. {
  120.         self->monsterinfo.currentmove = &flyer_move_stand;
  121. }
  122.  
  123. mframe_t flyer_frames_start [] =
  124. {
  125.         ai_move, 0,    NULL,
  126.         ai_move, 0,    NULL,
  127.         ai_move, 0,    NULL,
  128.         ai_move, 0,    NULL,
  129.         ai_move, 0,    NULL,
  130.         ai_move, 0,    flyer_nextmove
  131. };
  132. mmove_t flyer_move_start = {FRAME_hover01, FRAME_hover06, flyer_frames_start, NULL};
  133.  
  134. mframe_t flyer_frames_stop [] =
  135. {
  136.         ai_move, 0,    NULL,
  137.         ai_move, 0,    NULL,
  138.         ai_move, 0,    NULL,
  139.         ai_move, 0,    NULL,
  140.         ai_move, 0,    NULL,
  141.         ai_move, 0,    NULL,
  142.         ai_move, 0,    flyer_nextmove
  143. };
  144. mmove_t flyer_move_stop = {FRAME_hover06, FRAME_hover12, flyer_frames_stop, NULL};
  145.  
  146. void flyer_stop (edict_t *self)
  147. {
  148.         self->monsterinfo.currentmove = &flyer_move_stop;
  149. }
  150.  
  151. void flyer_start (edict_t *self)
  152. {
  153.         self->monsterinfo.currentmove = &flyer_move_start;
  154. }
  155.  
  156.  
  157. mframe_t flyer_frames_rollright [] =
  158. {
  159.         ai_move, 0, NULL,
  160.         ai_move, 0, NULL,
  161.         ai_move, 0, NULL,
  162.         ai_move, 0, NULL,
  163.         ai_move, 0, NULL,
  164.         ai_move, 0, NULL,
  165.         ai_move, 0, NULL,
  166.         ai_move, 0, NULL,
  167.         ai_move, 0, NULL,
  168.         ai_move, 0, NULL,
  169.         ai_move, 0, NULL,
  170.         ai_move, 0, NULL
  171. };
  172. mmove_t flyer_move_rollright = {FRAME_bankr01, FRAME_bankr12, flyer_frames_rollright, NULL};
  173.  
  174. mframe_t flyer_frames_rollleft [] =
  175. {
  176.         
  177.         ai_move, 0, NULL,
  178.         ai_move, 0, NULL,
  179.         ai_move, 0, NULL,
  180.         ai_move, 0, NULL,
  181.         ai_move, 0, NULL,
  182.         ai_move, 0, NULL,
  183.         ai_move, 0, NULL,
  184.         ai_move, 0, NULL,
  185.         ai_move, 0, NULL,
  186.         ai_move, 0, NULL,
  187.         ai_move, 0, NULL,
  188.         ai_move, 0, NULL
  189. };
  190. mmove_t flyer_move_rollleft = {FRAME_bankl01, FRAME_bankl12, flyer_frames_rollleft, NULL};
  191.  
  192. mframe_t flyer_frames_pain3 [] =
  193. {    
  194.         ai_move, 0, NULL,
  195.         ai_move, 0, NULL,
  196.         ai_move, 0, NULL,
  197.         ai_move, 0, NULL
  198. };
  199. mmove_t flyer_move_pain3 = {FRAME_hover01, FRAME_hover04, flyer_frames_pain3, flyer_run};
  200.  
  201. mframe_t flyer_frames_pain2 [] =
  202. {
  203.         ai_move, 0, NULL,
  204.         ai_move, 0, NULL,
  205.         ai_move, 0, NULL,
  206.         ai_move, 0, NULL
  207. };
  208. mmove_t flyer_move_pain2 = {FRAME_bankr01, FRAME_bankr04, flyer_frames_pain2, flyer_run};
  209.  
  210. mframe_t flyer_frames_pain1 [] =
  211. {
  212.         ai_move, 0, NULL,
  213.         ai_move, 0, NULL,
  214.         ai_move, 0, NULL,
  215.         ai_move, 0, NULL,
  216.         ai_move, 0, NULL,
  217.         ai_move, 0, NULL,
  218.         ai_move, 0, NULL,
  219.         ai_move, 0, NULL,
  220.         ai_move, 0, NULL
  221. };
  222. mmove_t flyer_move_pain1 = {FRAME_hover01, FRAME_hover09, flyer_frames_pain1, flyer_run};
  223.  
  224. mframe_t flyer_frames_defense [] = 
  225. {
  226.         ai_move, 0, NULL,
  227.         ai_move, 0, NULL,
  228.         ai_move, 0, NULL,        // Hold this frame
  229.         ai_move, 0, NULL,
  230.         ai_move, 0, NULL,
  231.         ai_move, 0, NULL
  232. };
  233. mmove_t flyer_move_defense = {FRAME_hover01, FRAME_hover06, flyer_frames_defense, NULL};
  234.  
  235. mframe_t flyer_frames_bankright [] =
  236. {
  237.         ai_move, 0, NULL,
  238.         ai_move, 0, NULL,
  239.         ai_move, 0, NULL,
  240.         ai_move, 0, NULL,
  241.         ai_move, 0, NULL,
  242.         ai_move, 0, NULL,
  243.         ai_move, 0, NULL,
  244.         ai_move, 0, NULL,
  245.         ai_move, 0, NULL,
  246.         ai_move, 0, NULL,
  247.         ai_move, 0, NULL,
  248.         ai_move, 0, NULL
  249. };
  250. mmove_t flyer_move_bankright = {FRAME_bankr01, FRAME_bankr12, flyer_frames_bankright, NULL};
  251.  
  252. mframe_t flyer_frames_bankleft [] =
  253. {
  254.         ai_move, 0, NULL,
  255.         ai_move, 0, NULL,
  256.         ai_move, 0, NULL,
  257.         ai_move, 0, NULL,
  258.         ai_move, 0, NULL,
  259.         ai_move, 0, NULL,
  260.         ai_move, 0, NULL,
  261.         ai_move, 0, NULL,
  262.         ai_move, 0, NULL,
  263.         ai_move, 0, NULL,
  264.         ai_move, 0, NULL,
  265.         ai_move, 0, NULL
  266. };
  267. mmove_t flyer_move_bankleft = {FRAME_bankl01, FRAME_bankl12, flyer_frames_bankleft, NULL};        
  268.  
  269.  
  270. void flyer_fire (edict_t *self, int flash_number)
  271. {
  272.     vec3_t    forward, right;
  273.     vec3_t    start;
  274.     vec3_t    end;
  275.     vec3_t    dir;
  276.     vec3_t from;
  277.     int damage = 15;
  278.     
  279.     trace_t     tr;
  280.     
  281.     AngleVectors (self->s.angles, forward, right, NULL);
  282.     G_ProjectSource (self->s.origin, monster_flash_offset[flash_number], forward, right, start);
  283.     VectorCopy (self->s.origin, start);
  284.     VectorCopy (self->enemy->s.origin, end);
  285.     end[2] += self->enemy->viewheight;
  286.     VectorSubtract (end, start, dir);
  287.     
  288.     VectorAdd(start, right, start);
  289.     end[2] = end[2] - 32;
  290.     if(self->spawnflags & 1)
  291.         start[2] = start[2] + 34;
  292.  
  293.     VectorCopy (start, from);
  294.     tr = gi.trace (from, NULL, NULL, end, self, MASK_SHOT);      
  295.     VectorCopy (tr.endpos, from);
  296.  
  297.  
  298.     gi.WriteByte (svc_temp_entity);
  299.     gi.WriteByte (TE_SHOTGUN);
  300.     gi.WritePosition (start);
  301.     gi.WritePosition (end);
  302.     gi.multicast (start, MULTICAST_PHS); 
  303.     
  304.     gi.WriteByte (svc_temp_entity);
  305.     gi.WriteByte (TE_BLASTER);
  306.     gi.WritePosition (end);
  307.     gi.WriteDir (tr.plane.normal);
  308.     gi.multicast (end, MULTICAST_PVS);
  309.     
  310.     gi.sound (self, CHAN_VOICE, sound_slash, 1, ATTN_NORM, 0);
  311.  
  312.     if ((tr.ent != self) && (tr.ent->takedamage))
  313.          T_Damage (tr.ent, self, self, dir, tr.endpos, tr.plane.normal, damage, 0, 0, MOD_HYPERBLASTER);
  314.     else if (!((tr.surface) && (tr.surface->flags & SURF_SKY)))
  315.     {  
  316.          gi.WriteByte (svc_temp_entity);
  317.          gi.WriteByte (TE_SCREEN_SPARKS);
  318.          gi.WritePosition (tr.endpos);
  319.          gi.WriteDir (tr.plane.normal);
  320.          gi.multicast (self->s.origin, MULTICAST_PVS);
  321.     }
  322.  
  323. }
  324.  
  325. void flyer_fireleft (edict_t *self)
  326. {
  327.     flyer_fire (self, MZ2_FLYER_BLASTER_1);
  328. }
  329.  
  330. void flyer_fireright (edict_t *self)
  331. {
  332.     flyer_fire (self, MZ2_FLYER_BLASTER_2);
  333. }
  334.  
  335.  
  336. mframe_t flyer_frames_attack2 [] =
  337. {
  338.         ai_charge, 0, NULL,
  339.         ai_charge, 0, NULL,
  340.         ai_charge, -10, flyer_fireleft,            
  341.         ai_charge, 0, NULL,
  342.         ai_charge, -10, flyer_fireright,        
  343.         ai_charge, -0, NULL,
  344.         ai_charge, -10, flyer_fireleft,            
  345.         ai_charge, -0, NULL,
  346.         ai_charge, -10, flyer_fireright,        
  347.         ai_charge, -0, NULL,
  348.         ai_charge, 0, NULL,
  349.         
  350.         ai_charge, 0, NULL
  351. };
  352. mmove_t flyer_move_attack2 = {FRAME_hover01, FRAME_hover12, flyer_frames_attack2, flyer_run};
  353.  
  354.  
  355. void flyer_slash_left (edict_t *self)
  356. {
  357.     vec3_t    aim;
  358.  
  359.     VectorSet (aim, MELEE_DISTANCE, self->mins[0], 0);
  360.     fire_hit (self, aim, 5, 0);
  361.     gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0);
  362. }
  363.  
  364. void flyer_slash_right (edict_t *self)
  365. {
  366.     vec3_t    aim;
  367.  
  368.     VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 0);
  369.     fire_hit (self, aim, 5, 0);
  370.     gi.sound (self, CHAN_WEAPON, sound_slash, 1, ATTN_NORM, 0);
  371. }
  372.  
  373. mframe_t flyer_frames_start_melee [] =
  374. {
  375.         ai_charge, 0, flyer_pop_blades,
  376.         ai_charge, 0, NULL,
  377.         ai_charge, 0, NULL,
  378.         ai_charge, 0, NULL,
  379.         ai_charge, 0, NULL,
  380.         ai_charge, 0, NULL
  381. };
  382. mmove_t flyer_move_start_melee = {FRAME_fly01, FRAME_fly06, flyer_frames_start_melee, flyer_loop_melee};
  383.  
  384. mframe_t flyer_frames_end_melee [] =
  385. {
  386.         ai_charge, 0, NULL,
  387.         ai_charge, 0, NULL,
  388.         ai_charge, 0, NULL
  389. };
  390. mmove_t flyer_move_end_melee = {FRAME_fly10, FRAME_fly12, flyer_frames_end_melee, flyer_run};
  391.  
  392.  
  393. mframe_t flyer_frames_loop_melee [] =
  394. {
  395.         ai_charge, 0, NULL,        // Loop Start
  396.         ai_charge, 0, NULL,
  397.         ai_charge, 0, flyer_slash_left,        // Left Wing Strike
  398.         ai_charge, 0, NULL,
  399.         ai_charge, 0, NULL,
  400.         ai_charge, 0, NULL,
  401.         ai_charge, 0, NULL,
  402.         ai_charge, 0, flyer_slash_right,    // Right Wing Strike
  403.         ai_charge, 0, NULL,
  404.         ai_charge, 0, NULL,
  405.         ai_charge, 0, NULL,
  406.         ai_charge, 0, NULL        // Loop Ends
  407.         
  408. };
  409. mmove_t flyer_move_loop_melee = {FRAME_fly01, FRAME_fly12, flyer_frames_loop_melee, flyer_check_melee};
  410.  
  411. void flyer_loop_melee (edict_t *self)
  412. {
  413. /*    if (random() <= 0.5)    
  414.         self->monsterinfo.currentmove = &flyer_move_attack1;
  415.     else */
  416.     self->monsterinfo.currentmove = &flyer_move_loop_melee;
  417. }
  418.  
  419.  
  420.  
  421. void flyer_attack (edict_t *self)
  422. {
  423. /*    if (random() <= 0.5)    
  424.         self->monsterinfo.currentmove = &flyer_move_attack1;
  425.     else */
  426.     self->monsterinfo.currentmove = &flyer_move_attack2;
  427. }
  428.  
  429. void flyer_setstart (edict_t *self)
  430. {
  431.     nextmove = ACTION_run;
  432.     self->monsterinfo.currentmove = &flyer_move_start;
  433. }
  434.  
  435. void flyer_nextmove (edict_t *self)
  436. {
  437.     if (nextmove == ACTION_attack1)
  438.         self->monsterinfo.currentmove = &flyer_move_start_melee;
  439.     else if (nextmove == ACTION_attack2)
  440.         self->monsterinfo.currentmove = &flyer_move_attack2;
  441.     else if (nextmove == ACTION_run)
  442.         self->monsterinfo.currentmove = &flyer_move_run;
  443. }
  444.  
  445. void flyer_melee (edict_t *self)
  446. {
  447. //    flyer.nextmove = ACTION_attack1;
  448. //    self->monsterinfo.currentmove = &flyer_move_stop;
  449.     self->monsterinfo.currentmove = &flyer_move_start_melee;
  450. }
  451.  
  452. void flyer_check_melee(edict_t *self)
  453. {
  454.     if (range (self, self->enemy) == RANGE_MELEE)
  455.         if (random() <= 0.8)
  456.             self->monsterinfo.currentmove = &flyer_move_loop_melee;
  457.         else
  458.             self->monsterinfo.currentmove = &flyer_move_end_melee;
  459.     else
  460.         self->monsterinfo.currentmove = &flyer_move_end_melee;
  461. }
  462.  
  463. void flyer_pain (edict_t *self, edict_t *other, float kick, int damage)
  464. {
  465.     int        n;
  466.  
  467.     if (self->health < (self->max_health / 2))
  468.         self->s.skinnum = 1;
  469.  
  470.     if (level.time < self->pain_debounce_time)
  471.         return;
  472.  
  473.     self->pain_debounce_time = level.time + 3;
  474.     if (skill->value == 3)
  475.         return;        // no pain anims in nightmare
  476.  
  477.     n = rand() % 3;
  478.     if (n == 0)
  479.     {
  480.         gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
  481.         self->monsterinfo.currentmove = &flyer_move_pain1;
  482.     }
  483.     else if (n == 1)
  484.     {
  485.         gi.sound (self, CHAN_VOICE, sound_pain2, 1, ATTN_NORM, 0);
  486.         self->monsterinfo.currentmove = &flyer_move_pain2;
  487.     }
  488.     else
  489.     {
  490.         gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
  491.         self->monsterinfo.currentmove = &flyer_move_pain3;
  492.     }
  493. }
  494.  
  495.  
  496. void flyer_die(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
  497. {
  498.     gi.sound (self, CHAN_VOICE, sound_die, 1, ATTN_NORM, 0);
  499.     BecomeExplosion1(self);
  500. }
  501.     
  502.  
  503. /*QUAKED monster_flyer (1 .5 0) (-16 -16 -24) (16 16 32) Ambush Trigger_Spawn Sight
  504. */
  505. void SP_monster_saucer (edict_t *self)
  506. {
  507.     if (deathmatch->value)
  508.     {
  509.         G_FreeEdict (self);
  510.         return;
  511.     }
  512.  
  513.     // fix a map bug in jail5.bsp
  514.     if (!stricmp(level.mapname, "jail5") && (self->s.origin[2] == -104))
  515.     {
  516.         self->targetname = self->target;
  517.         self->target = NULL;
  518.     }
  519.  
  520.     sound_sight = gi.soundindex ("flyer/flysght1.wav");
  521.     sound_idle = gi.soundindex ("flyer/flysrch1.wav");
  522.     sound_pain1 = gi.soundindex ("flyer/flypain1.wav");
  523.     sound_pain2 = gi.soundindex ("flyer/flypain2.wav");
  524.     sound_slash = gi.soundindex ("martian/shoot1.wav");
  525.     sound_sproing = gi.soundindex ("martian/shoot2.wav");
  526.     sound_die = gi.soundindex ("flyer/flydeth1.wav");
  527.  
  528.     if(self->spawnflags & 1)
  529.         self->s.modelindex = gi.modelindex ("models/monsters/martian_warship/tris.md2");
  530.     else
  531.         self->s.modelindex = gi.modelindex ("models/monsters/martian_saucer/tris.md2");
  532.     if(self->spawnflags & 1)
  533.     {
  534.         VectorSet (self->mins, -64, -64, -24);
  535.         VectorSet (self->maxs, 64, 64, 64);
  536.     }
  537.     else
  538.     {
  539.         VectorSet (self->mins, -64, -64, 16);
  540.         VectorSet (self->maxs, 64, 64, 156);
  541.     }
  542.     self->movetype = MOVETYPE_STEP;
  543.     self->solid = SOLID_BBOX;
  544.     self->classname = "monster_saucer";
  545.     
  546.     if(self->spawnflags & 1)
  547.         self->s.sound = gi.soundindex ("flyer/flyidle1.wav");
  548.     else
  549.         self->s.sound = gi.soundindex ("martian/saucer.wav");
  550.  
  551.     self->health = 250;
  552.     self->mass = 250;
  553.  
  554.     self->pain = flyer_pain;
  555.     self->die = flyer_die;
  556.  
  557.     self->monsterinfo.stand = flyer_stand;
  558.     self->monsterinfo.walk = flyer_walk;
  559.     self->monsterinfo.run = flyer_run;
  560.     self->monsterinfo.attack = flyer_attack;
  561.     self->monsterinfo.melee = flyer_melee;
  562.     self->monsterinfo.sight = flyer_sight;
  563.     self->monsterinfo.idle = flyer_idle;
  564.  
  565.     gi.linkentity (self);
  566.  
  567.     self->monsterinfo.currentmove = &flyer_move_stand;    
  568.     self->monsterinfo.scale = MODEL_SCALE;
  569.  
  570.     flymonster_start (self);
  571. }
  572.